package com.witframework.core.persistence;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.extremecomponents.table.context.Context;
import org.extremecomponents.table.context.HttpServletRequestContext;
import org.extremecomponents.table.core.TableConstants;
import org.extremecomponents.table.filter.ExportFilterUtils;
import org.extremecomponents.table.limit.Limit;
import org.extremecomponents.table.limit.LimitFactory;
import org.extremecomponents.table.limit.LimitRegistry;
import org.extremecomponents.table.limit.TableLimit;
import org.extremecomponents.table.limit.TableLimitFactory;
import org.springframework.web.util.WebUtils;

import com.witframework.core.PropertiesUtil;
import com.witframework.core.SerialChecker;
import com.witframework.util.BeanUtils;
import com.witframework.web.util.RequestInvalidException;

/**
 * 分页排序 支持对extremecomponents's table状态保持的支持（state="persist"）
 * 
 * @author wuxinyang
 * 
 */
public class PageSortModel{
	private int pageSize = 10;// 页面大小
	private int pageNo = 1;// 页号
	private transient int totalRows = 0;// 总记录数
	private transient int pageCount = 0;// 总页数
	private boolean all = false;
	private Map orderMap = new HashMap();
	private Limit limit = null;
	private HttpServletRequest request = null;
	private String tableId = "ec";
	
	public PageSortModel(){
		pageSize=1000000;
		
	}
	public PageSortModel(HttpServletRequest request) {		
		this(request,null);
	}
	/**
	 * 构造方法 这里默认的state="persist",如果要使用其他的state设置，也许应该作为参数传入（呵呵）。
	 * 
	 * @param request   -HttpServletRequest
	 * @param table_id  用于区分多个table的Id，如果是单个table可以是null。
	 *            一般应该设置该tableId，以便清楚的知道是那个table,^_^
	 * 
	 */
	public PageSortModel(HttpServletRequest request, String table_id) {
		pageSize=Integer.parseInt(PropertiesUtil.loadProperties("config/extremetable.properties").getProperty("table.rowsDisplayed", "10"));
		if (request == null)
			throw new RequestInvalidException(	"HttpServletRequest is Invalid.ERROR!!!");
		this.request = request;
		tableId = (String) request.getParameter(TableConstants.EXTREME_COMPONENTS_INSTANCE);
		if (tableId == null||tableId.equals(""));
			tableId = table_id;
		Context context = new HttpServletRequestContext(request);
		LimitFactory limitFactory = new TableLimitFactory(context, tableId,TableConstants.STATE_PERSIST, null);
		limit = new TableLimit(limitFactory);
		setPageNo(limit.getPage());// 当前页号
		SerialChecker.check();
		String rcdStr = context.getParameter(tableId + "_crd");
		try {
			// 读取当前的页面大小
			LimitRegistry lr = (LimitRegistry) BeanUtils.getDeclaredProperty(limitFactory, "registry");
			setPageSize(Integer.parseInt(lr.getParameter(tableId + "_crd")));
		} catch (Exception e) {
			if (rcdStr == null) {
				HashMap ec_values = (HashMap) request.getSession().getAttribute("s_ec");
				if (ec_values != null) {
					String[] rcd = (String[]) ec_values.get("ec_crd");
					if (rcd != null)
						setPageSize(Integer.parseInt(rcd[0]));// 页大小
				}
			} else {
				setPageSize(Integer.parseInt(rcdStr));// 页大小
			}
		}

		// 判断是否是导出 如果是则不分页，取出所有数据
		if (ExportFilterUtils.isExported(context)){
			all = true;
		}
		HashMap stateMap = (HashMap) request.getSession().getAttribute(	TableConstants.STATE + tableId);
		// 从parameters取
		orderMap = WebUtils.getParametersStartingWith(request, tableId + "_"+ TableConstants.SORT);
		if (stateMap != null && (orderMap == null || orderMap.size() == 0)) {
			// 从Session中的state数据取当前的排序字段设置
			orderMap = getOrderMap(stateMap, tableId + "_"+ TableConstants.SORT);
		}
		Map<String, String> newOrderMap = new HashMap();
		Iterator keys = orderMap.keySet().iterator();
		while (keys.hasNext()) {
			String key = (String) keys.next();
			String value ;
			try{
			 value = (String) orderMap.get(key);
			}catch(Exception e){continue;}
			String skey = tableId + "_" + TableConstants.ALIAS + key;
			String sValue = stateMap.get(skey)!=null?((String[])stateMap.get(skey))[0]:null;
			if (StringUtils.isNotEmpty(sValue)) {
				newOrderMap.put(sValue, request.getParameter(tableId + "_" + TableConstants.SORT + key));
			} else if(StringUtils.isNotEmpty(value)){
				newOrderMap.put(key, value);
			}
		}
		orderMap = newOrderMap;
	}
	
	public PageSortModel(int pageNo) {
		this.pageNo = pageNo;
	}

	public Map getOrderMap() {
		return orderMap;
	}

	public int getPageCount() {
		return pageCount;
	}

	public void setPageCount(int pageCount) {
		this.pageCount = pageCount;
	}

	public int getPageNo() {		
		return pageNo<=0?1:pageNo;
	}

	public void setPageNo(int pageNo) {
		this.pageNo = (pageNo<=0?1:pageNo);
	}

	public void resetPageNo(int pageNo) {
		setPageNo(pageNo);
		if (limit != null)
			try {
				BeanUtils.setDeclaredProperty(limit, "page",new Integer(getPageNo()));
				BeanUtils.setDeclaredProperty(limit, "rowStart", new Integer((getPageNo() - 1) * pageSize + 1));
				BeanUtils.setDeclaredProperty(limit, "rowEnd", new Integer((getPageNo()) * pageSize - 1));
				request.getSession().setAttribute(tableId + "_" + TableConstants.PAGE,new Integer(getPageNo()));
				request.setAttribute(tableId + "_" + TableConstants.PAGE,new Integer(getPageNo()));
				Object o = request.getSession().getAttribute("s_" + tableId);
				if (o != null & o instanceof HashMap) {
					HashMap mp = (HashMap) o;
					mp.put(tableId + "_p", new String[] { "" + getPageNo() });
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
	}

	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	public int getTotalRows() {
		return totalRows;
	}

	public void setTotalRows(int totalRows) {
		this.totalRows=totalRows;
		if (limit != null) {
			
			limit.setRowAttributes(totalRows, getPageSize());			
			request.setAttribute(tableId+"_totalRows", new Integer(totalRows));			
		}
		setPageCount((int) Math.ceil(totalRows * 1.0 / getPageSize()));		
	}
	/**
	 * 取当前页面的开始记录号
	 * @return
	 */
	public int getStartOfPage() {
		return (getPageNo() - 1) * getPageSize();
	}
	/**
	 * 取当前页面的结束记录号
	 * @return
	 */
	public int getEndOdPage(){
		return getStartOfPage()+this.getPageSize();
	}
	public boolean isAll() {
		return all;
	}

	public void setAll(boolean all) {
		this.all = all;
	}

	private Map getOrderMap(Map maps, String s) {
		Map result = new HashMap();
		for (Iterator iter = maps.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String value = ((String[]) maps.get(name))[0];
			if (StringUtils.isNotEmpty(value) && name.startsWith(s)) {
				result.put(name.substring(s.length()), value);
			}
		}
		return result;
	}

	/**
	 * 增加排序字段
	 * 
	 * @param attr
	 *            需要排序的字段名称（class's attribute name）
	 * @param order
	 *            排序类型（asc,desc）
	 */
	public PageSortModel addOrder(String attr, String order) {
		orderMap.put(attr, order);
		return this;
	}
	
}
